import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:animal/socket/base.dart';
import 'package:animal/socket/base_model.dart';
import 'package:animal/socket/socket_message_model/friend_message_model.dart';
import 'package:animal/utils/sputils/sp_config.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:hive/hive.dart';

import 'messsage_model.dart';

class ClientSocket extends GetxController {
  Socket? glSock; // 拿到socket实例，存储到provide中，便于其他页面使用socket的方法

  Map? response; // 接收socket返回回来的数据

  dynamic glContext; // 存储传入进来的context，provide的方法在调用时需要传

  String token = ""; // 获取本地token

  bool netWorkStatus = true; // 网络状态

  bool socketStatus = false; // socket状态

  Timer? _timer;

  var box = Hive.box('messageBox');

  /// 初始化socket连接
  void connect(context) async {
    // 获取本地存储Token
    token = SpConfig().getUserToken()!;

    // 判断token是否为空并且网络状态是否为没有网络：停止心跳发送
    if (token.isEmpty || !netWorkStatus) {
      _timer = null;
      return;
    }

    //创建一个Socket连接到指定地址与端口
    await Socket.connect('192.168.0.59', 8088).then((socket) async {
      debugPrint('---------连接成功------------');

      socketStatus = true;

      glSock = socket;

      glContext = context;

      // 存储全局socket对象
      // Provide.value<SocketProvider>(context).setSocket(gl_sock);
      // 全局的socket设置为在线状态,该方法由项目决定酌情添加
      // Provide.value<SocketProvider>(context).setOnlineSocket(true);

      // 向服务器发送token验证
      String model = await BaseModel().baseData(0).then((value) => jsonEncode(value) + SocketBase.lastString);
      debugPrint(jsonEncode(MessageModel().toJson()) + SocketBase.lastString);
      debugPrint(model);
      box.add(jsonDecode(model.replaceAll(SocketBase.lastString, "")));
      glSock!.write(model);
      // glSock!.write(jsonEncode(MessageModel().toJson())+SocketBase.lastString);
      // socket监听
      glSock!.listen(dataHandler,
          // onError: errorHandler,
          onDone: doneHandler,
          cancelOnError: false);
      // gl_sock.close();
    }).catchError((e) {
      debugPrint("socket无法连接: $e");
    });
  }

  // 接收socket返回报文
  dataHandler(data) async {
    debugPrint('-------Socket发送来的消息-------');
    var cnData = utf8.decode(data); // 将信息转为正常文字
    debugPrint(cnData);
    response = json.decode(cnData.replaceAll("\$qwer\$", ""));
    // 判断返回的状态信息token验证是否成功，如果相等，变可以socket通信
    if (response!["ht"] == 0) {
      SmartDialog.showToast('欢迎登录~');
      // 给后台发送心跳
      heartbeatSocket();
      return;
    } else if (response!["ht"] == 2) {
      heartbeatSocket();
      return;
    } else if (response!["ht"] == 3) {
      //如果接收到的是系统反馈的状态消息，不会保存在消息列表中
      if(response!["snt"] != 0){
        box.add(response);
      }
      //将发送的消息进行比对消息id，如果系统返回的消息状态是成功，将消息状态改为发送成功；
      for(int i = 0;i<box.length;i++){
        if(response!["snt"]==0 && box.getAt(i)["i"] == response!["mr"]["i"]){
          box.getAt(i)["s"] = 1;
          box.put(i, box.getAt(i));
          debugPrint("这是存储的数据进行更改"+box.getAt(i).toString());
        }
      }
    } else if (response!["ht"] == null) {
      SmartDialog.showToast("发送失败：${response!["m"]}");
      return;
    }

    // 判断 服务器返回的接收人id和发送人id如果不是同一个的话，开始进行socket信息的存储
    // recv_id:接收人、send_id：发送人
    // if(response['recv_id'] != int.parse(response['send_id'])){
    //   // 判断消息类型，存储到provide消息实体当中
    //   switch (response['content_type']) {
    //     case 'text':
    //       Provide.value<SocketProvider>(gl_context).setRecords(response['Content'], 'text',  false);
    //       break;
    //     case 'img':
    //       Provide.value<SocketProvider>(gl_context).setRecords(response['Content'],'img', false);
    //       break;
    //     case 'video':
    //       Provide.value<SocketProvider>(gl_context).setRecords(response['Content'],'video',  false);
    //       break;
    //     case 'audio':
    //       Provide.value<SocketProvider>(gl_context).setRecords(response['Content'],'audio', false, time_length:response['time_length']);
    //       break;
    //     default:
    //   }
    // }
  }

  // Socket出现断开的问题
  void doneHandler() {
    socketStatus = false;
    SmartDialog.dismiss(); // 清空所有弹窗
    reconnectSocket(); //调用重连socket方法
  }

  // 重新连接socket
  void reconnectSocket() {
    int count = 0;
    const period = Duration(seconds: 10);
    // 定时器
    Timer.periodic(period, (timer) {
      // 每一次重连之前，都删除关掉上一个socket
      // gl_sock.close();
      glSock = null;
      count++;
      if (count >= 3) {
        debugPrint('时间到了!!!开始从连socket');
        // 链接socket
        connect(glContext); // 重连
        count = 0; // 倒计时设置为0
        timer.cancel(); // 清空倒计时
        SmartDialog.dismiss(); // 关闭弹框
      }
    });
  }

  // 心跳机，每15秒给后台发送一次，用来保持连接
  void heartbeatSocket() {
    const duration = Duration(seconds: 10);
    _timer = Timer(duration, () async {
      // 如果socket状态是断开的，就停止定时器
      if (!socketStatus) {
        _timer!.cancel();
      }
      // var _subscription = Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
      //   // print('--------------------当前网络：$result------------------------');
      //   if (result != ConnectivityResult.mobile && result != ConnectivityResult.wifi) {
      //     debugPrint('没有网络，停止定时器');
      //     netWorkStatus = false;
      //     time.cancel();
      //   } else {
      //     netWorkStatus = true;
      //   }
      // });

      // token = SpConfig().getUserToken()!;
      //
      // // token为空，关闭定时器
      // if (token.isEmpty) {
      //   time.cancel();
      //   return;
      // }
      debugPrint('-----------------发送心跳------------------');
      String data = await BaseModel().heartData(2).then((value) => json.encode(value) + SocketBase.lastString);
      glSock!.write(data);
    });
  }

  @override
  void dispose() {
    _timer!.cancel();
    super.dispose();
  }
}
